package com.hjw.httpclient.retry;

import org.apache.http.*;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.ServiceUnavailableRetryStrategy;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 *自定义的重试策略类，用来实现可达请求的重试（com.hjw.httpclient.retry.MyRetryResponseCode）
 * @author hjwStrart
 * @time 2022-11-23 20:09
 * @version: 1.0
 */
@ConfigurationProperties(prefix = "my-retry-response-code")
@ConstructorBinding
public class MyRetryStrategy implements ServiceUnavailableRetryStrategy {

    private final int MAX_RETRY_COUNT;
    private final int RETRY_INTERVAL;


    public MyRetryStrategy(int maxRetryCount, int retryInterval) {
        MAX_RETRY_COUNT = maxRetryCount;
        RETRY_INTERVAL = retryInterval;
    }


    /**
     * 重试逻辑
     *
     * @param response       服务器的响应内容
     * @param executionCount 当前重试次数
     * @param context        当前请求的上下文内容
     * @return
     */
    @Override
    public boolean retryRequest(HttpResponse response, int executionCount, HttpContext context) {
        if (executionCount <= MAX_RETRY_COUNT){
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                System.out.println("请求成功");
            }else if (statusCode == HttpStatus.SC_BAD_REQUEST){
                System.out.println("请求参数错误");
            }else if (statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR){
                System.out.println("服务器内部错误");
            }else{
                System.out.println("未知错误");
            }

            HttpClientContext clientContext = HttpClientContext.adapt(context);
            HttpRequest request = clientContext.getRequest();
            boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
            if (idempotent) {
                // Retry if the request is considered idempotent （判断当前请求是否是幂等请求）
                return true;
            }

            return true;

        }
        return false;
    }

    /**
     * 重试间隔
     *
     * @return
     */
    @Override
    public long getRetryInterval() {
        return RETRY_INTERVAL;
    }

    @Override
    public String toString() {
        return "MyRetryStrategy{" +
                "MAX_RETRY_COUNT=" + MAX_RETRY_COUNT +
                ", RETRY_INTERVAL=" + RETRY_INTERVAL +
                '}';
    }
}
